Micron Document
NexusPi Git Node


Displaying Raw • Download

lib/microReticulum/src/Link.cpp v1.0.7 (59784a34) Text, 63.10 KB

Tff7b72#Tff7b72include T8b949e"Link.h"

Tff7b72#Tff7b72include T8b949e"LinkData.h"
Tff7b72#Tff7b72include T8b949e"Resource.h"
Tff7b72#Tff7b72include T8b949e"Reticulum.h"
Tff7b72#Tff7b72include T8b949e"Transport.h"
Tff7b72#Tff7b72include T8b949e"Packet.h"
Tff7b72#Tff7b72include T8b949e"Log.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Ed25519.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/X25519.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/HKDF.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Token.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Random.h"
Tff7b72#Tff7b72include T8b949e"Utilities/OS.h"

Tff7b72#Tff7b72define MSGPACK_DEBUGLOG_ENABLE 0
Tff7b72#Tff7b72include T8b949e<MsgPack.h>

Tff7b72#Tff7b72include T8b949e<math.h>

Tff7b72#Tff7b72include T8b949e<algorithm>

Tff7b72using Tff7b72namespace T7ee787RNSTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787TypeTff7b72:Tff7b72:T7ee787LinkTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787CryptographyTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787UtilitiesTb4b4b4;

T8b949e/*static*/ Tffa657uint8_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3resource_strategies Tff7b72= Te6edf3ACCEPT_NONE Tff7b72| Te6edf3ACCEPT_APP Tff7b72| Te6edf3ACCEPT_ALLTb4b4b4;

T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3link_modeTff7b72> Te6edf3LinkTff7b72:Tff7b72:Te6edf3ENABLED_MODES Tff7b72= Tb4b4b4{Te6edf3MODE_AES256_CBCTb4b4b4}Tb4b4b4;
T8b949e/*static*/ Te6edf3link_mode Te6edf3LinkTff7b72:Tff7b72:Te6edf3MODE_DEFAULT Tff7b72= Te6edf3MODE_AES256_CBCTb4b4b4;

Te6edf3LinkTff7b72:Tff7b72:Te6edf3LinkTb4b4b4(Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destination T8b949e/*= {Type::NONE}*/Tb4b4b4, Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3established Te6edf3established_callback T8b949e/*= nullptr*/Tb4b4b4, Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3closed Te6edf3closed_callback T8b949e/*= nullptr*/Tb4b4b4, Tff7b72const Te6edf3DestinationTff7b72& Te6edf3owner T8b949e/*= {Type::NONE}*/Tb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3peer_pub_bytes T8b949e/*= {Bytes::NONE}*/Tb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3peer_sig_pub_bytes T8b949e/*= {Bytes::NONE}*/Tb4b4b4, Te6edf3link_mode Te6edf3mode T8b949e/*= MODE_DEFAULT*/Tb4b4b4) Tff7b72:
Te6edf3_objectTb4b4b4(Tff7b72new Te6edf3LinkDataTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4)
Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_owner Tff7b72= Te6edf3ownerTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mode Tff7b72= Te6edf3modeTb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3destination Tff7b72&Tff7b72& Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3logic_errorTb4b4b4(Ta5d6ff"Ta5d6ffLinks can only be established to the Tffea00\"Ta5d6ffsingleTffea00\"Ta5d6ff destination typeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Tff7b72!Te6edf3destinationTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiator Tff7b72= Tffa657falseTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3X25519PrivateKeyTff7b72:Tff7b72:Te6edf3generateTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// CBA BUG: not checking for owner
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_ownerTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_ownerTb4b4b4.Te6edf3identityTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sig_prvTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiator Tff7b72= Tffa657trueTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_expected_hops Tff7b72= Te6edf3TransportTff7b72:Tff7b72:Te6edf3hops_toTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_timeout Tff7b72= Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3get_instanceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3get_first_hop_timeoutTb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3X25519PrivateKeyTff7b72:Tff7b72:Te6edf3generateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3Ed25519PrivateKeyTff7b72:Tff7b72:Te6edf3generateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pubTff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink::load_private_key: pub bytes: %sTa5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytesTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pubTff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink::load_private_key: sig pub bytes: %sTa5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytesTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Tff7b72!Te6edf3peer_pub_bytesTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub Tff7b72= Tffa657nullptrTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub_bytes Tff7b72= Tffa657nullptrTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3load_peerTb4b4b4(Te6edf3peer_pub_bytesTb4b4b4, Te6edf3peer_sig_pub_bytesTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3established_callbackTb4b4b4) Tb4b4b4{
Te6edf3set_link_established_callbackTb4b4b4(Te6edf3established_callbackTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3closed_callbackTb4b4b4) Tb4b4b4{
Te6edf3set_link_closed_callbackTb4b4b4(Te6edf3closed_callbackTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3signalling_bytesTb4b4b4;
Tffa657uint16_t Te6edf3nh_hw_mtu Tff7b72= Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interface_hw_mtuTb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3link_mtu_discoveryTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3nh_hw_mtuTb4b4b4) Tb4b4b4{
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3nh_hw_mtuTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_modeTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSignalling link MTU of %d for linkTa5d6ff"Tb4b4b4, Te6edf3nh_hw_mtuTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_modeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffEstablishing link with mode %dTa5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_modeTb4b4b4)Tb4b4b4;
T8b949e//p self.request_data = self.pub_bytes+self.sig_pub_bytes+signalling_bytes
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_data Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytes Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytes Tff7b72+ Te6edf3signalling_bytesTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet Tff7b72= Te6edf3PacketTb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_dataTb4b4b4, Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packetTb4b4b4.Te6edf3packTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72+Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3set_link_idTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packetTb4b4b4)Tb4b4b4;
Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_linkTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3start_watchdogTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink request %s sent to %sTa5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffEstablishment timeout is %f for link request %sTa5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_timeoutTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e// CBA LINK
T8b949e//_object->_link_destination = Destination({Type::NONE}, Type::Destination::OUT, Type::Destination::LINK, hash());
T8b949e//_object->_link_destination.link_id(_object->_link_id);

Te6edf3MEMTb4b4b4(Ta5d6ff"Ta5d6ffLink object createdTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}


T8b949e/*static*/ Te6edf3Bytes Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Tffa657uint16_t Te6edf3mtuTb4b4b4, Te6edf3link_mode Te6edf3modeTb4b4b4) Tb4b4b4{
T8b949e//p if not mode in Link.ENABLED_MODES: raise TypeError(f"Requested link mode {Link.MODE_DESCRIPTIONS[mode]} not enabled")
T8b949e//if (!(mode & ENABLED_MODES)) throw std::runtime_error("Requested link mode "+std::to_string(mode)+" not enabled");
Tff7b72if Tb4b4b4(Te6edf3LinkTff7b72:Tff7b72:Te6edf3ENABLED_MODESTb4b4b4.Te6edf3findTb4b4b4(Te6edf3modeTb4b4b4) Tff7b72=Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3ENABLED_MODESTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffRequested link mode Ta5d6ff"Tff7b72+Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3modeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff not enabledTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//p signalling_value = (mtu & Link.MTU_BYTEMASK)+(((mode<<5) & Link.MODE_BYTEMASK)<<16)
T8b949e//p return struct.pack(">I", signalling_value)[1:]
Tffa657uint32_t Te6edf3signalling_value Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3portable_htonlTb4b4b4(Tb4b4b4(Te6edf3mtu Tff7b72& Te6edf3MTU_BYTEMASKTb4b4b4)Tff7b72+Tb4b4b4(Tb4b4b4(Tb4b4b4(Te6edf3modeTff7b72<Tff7b72<T79c0ff5Tb4b4b4) Tff7b72& Te6edf3MODE_BYTEMASKTb4b4b4)Tff7b72<Tff7b72<T79c0ff16Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Td2a8ffdataTb4b4b4(Tb4b4b4(Tb4b4b4(Tffa657uint8_tTff7b72*Tb4b4b4)Tff7b72&Te6edf3signalling_valueTb4b4b4)Tff7b72+T79c0ff1Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3dataTb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Tffa657uint16_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ECPUBSIZETff7b72+Te6edf3LINK_MTU_SIZETb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4[Te6edf3ECPUBSIZETb4b4b4] Tff7b72<Tff7b72< T79c0ff16Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4[Te6edf3ECPUBSIZETff7b72+T79c0ff1Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4[Te6edf3ECPUBSIZETff7b72+T79c0ff2Tb4b4b4]Tb4b4b4) Tff7b72& Te6edf3MTU_BYTEMASKTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Tffa657uint16_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lp_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e//p if len(packet.data) == RNS.Identity.SIGLENGTH//8+Link.ECPUBSIZE//2+Link.LINK_MTU_SIZE:
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tff7b72+Te6edf3LINK_MTU_SIZETb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3mtu_bytes Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4, Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3mtu_bytesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff16Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3mtu_bytesTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3mtu_bytesTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4) Tff7b72& Te6edf3MTU_BYTEMASKTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Tffa657uint8_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_byteTb4b4b4(Te6edf3link_mode Te6edf3modeTb4b4b4) Tb4b4b4{
T8b949e//p if mode in Link.ENABLED_MODES: return (mode << 5) & Link.MODE_BYTEMASK
Tff7b72if Tb4b4b4(Te6edf3LinkTff7b72:Tff7b72:Te6edf3ENABLED_MODESTb4b4b4.Te6edf3findTb4b4b4(Te6edf3modeTb4b4b4) Tff7b72!Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3ENABLED_MODESTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Tb4b4b4(Te6edf3mode Tff7b72<Tff7b72< T79c0ff5Tb4b4b4) Tff7b72& Te6edf3MODE_BYTEMASKTb4b4b4;
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffRequested link mode {mode} not enabledTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Te6edf3link_mode Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3ECPUBSIZETb4b4b4) Tb4b4b4{
Te6edf3link_mode Te6edf3mode Tff7b72= Tff7b72static_castTff7b72<Te6edf3link_modeTff7b72>Tb4b4b4(Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4[Te6edf3ECPUBSIZETb4b4b4] Tff7b72& Te6edf3MODE_BYTEMASKTb4b4b4) Tff7b72>Tff7b72> T79c0ff5Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3modeTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3LinkTff7b72:Tff7b72:Te6edf3MODE_DEFAULTTb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Te6edf3link_mode Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lp_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3link_mode Te6edf3mode Tff7b72= Tff7b72static_castTff7b72<Te6edf3link_modeTff7b72>Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4[Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4] Tff7b72>Tff7b72> T79c0ff5Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3modeTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3LinkTff7b72:Tff7b72:Te6edf3MODE_DEFAULTTb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Te6edf3Bytes Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3hashable_part Tff7b72= Te6edf3packetTb4b4b4.Te6edf3get_hashable_partTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3ECPUBSIZETb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3diff Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3ECPUBSIZETb4b4b4;
T8b949e//p hashable_part = hashable_part[:-diff]
Te6edf3hashable_part Tff7b72= Te6edf3hashable_partTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3hashable_partTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3diffTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3RNSTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3hashable_partTb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/*static*/ Te6edf3Link Te6edf3LinkTff7b72:Tff7b72:Te6edf3validate_requestTb4b4b4( Tff7b72const Te6edf3DestinationTff7b72& Te6edf3ownerTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4, Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ECPUBSIZE Tff7b72|Tff7b72| Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ECPUBSIZE Tff7b72+ Te6edf3LINK_MTU_SIZETb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3Link Te6edf3linkTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Tffa657nullptrTb4b4b4, Tffa657nullptrTb4b4b4, Te6edf3ownerTb4b4b4, Te6edf3dataTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4, Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4, Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3set_link_idTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ECPUBSIZE Tff7b72+ Te6edf3LINK_MTU_SIZETb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLink request includes MTU signallingTa5d6ff"Tb4b4b4)Tb4b4b4; T8b949e// TODO: Remove debug
Tff7b72try Tb4b4b4{
Tffa657uint16_t Te6edf3mtu Tff7b72= Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3mtuTb4b4b4(Tb4b4b4(Te6edf3mtu Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tff7b72? Te6edf3mtu Tff7b72: Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while validating link request %sTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3mtuTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Te6edf3linkTb4b4b4.Te6edf3modeTb4b4b4(Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4)Tb4b4b4;

T8b949e// TODO: Remove debug
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffIncoming link request with mode %dTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3get_modeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;

Te6edf3linkTb4b4b4.Te6edf3update_mduTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3establishment_timeoutTb4b4b4(Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Te6edf3KEEPALIVETb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3establishment_costTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3establishment_costTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffValidating link request %sTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink MTU configured to %dTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3mtuTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffEstablishment timeout is %f for incoming link request %sTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3establishment_timeoutTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3handshakeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3request_timeTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_linkTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3last_inboundTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3start_watchdogTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffIncoming link request %s acceptedTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3linkTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffValidating link request failed, exception: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link request payload size (%zu), dropping requestTa5d6ff"Tb4b4b4, Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3load_peerTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3peer_pub_bytesTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3peer_sig_pub_bytesTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub_bytes Tff7b72= Te6edf3peer_pub_bytesTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3X25519PublicKeyTff7b72:Tff7b72:Te6edf3from_public_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub_bytesTb4b4b4)Tb4b4b4;

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_sig_pub_bytes Tff7b72= Te6edf3peer_sig_pub_bytesTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_sig_pub Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3Ed25519PublicKeyTff7b72:Tff7b72:Te6edf3from_public_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_sig_pub_bytesTb4b4b4)Tb4b4b4;

T8b949e// CBA TODO Determine the purpose of the following.
T8b949e// X25519PublicKey does not have a member "curve" and this is not accessed anywhere
T8b949e/*
if not hasattr(self.peer_pub, "curve") {
self.peer_pub.curve = CURVE;
}
*/
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_link_idTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_id Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hash Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3handshakeTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3PENDING Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3HANDSHAKETb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_shared_key Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTff7b72-Tff7b72>Te6edf3exchangeTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub_bytesTb4b4b4)Tb4b4b4;

Tffa657uint16_t Te6edf3derived_key_lengthTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mode Tff7b72=Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3MODE_AES128_CBCTb4b4b4) Te6edf3derived_key_length Tff7b72= T79c0ff32Tb4b4b4;
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mode Tff7b72=Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3MODE_AES256_CBCTb4b4b4) Te6edf3derived_key_length Tff7b72= T79c0ff64Tb4b4b4;
Tff7b72else Tff7b72throw Tff7b72new Te6edf3stdTff7b72:Tff7b72:Te6edf3invalid_argumentTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link mode Ta5d6ff"Tff7b72+Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_modeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff on Ta5d6ff"Tff7b72+Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_derived_key Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3derived_key_lengthTb4b4b4,
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_shared_keyTb4b4b4,
Te6edf3get_saltTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3get_contextTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffHandshake attempt on %s with invalid state %dTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_statusTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3proveTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s requesting proofTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3signed_data Tff7b72=Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_id Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytes Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytesTb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffsignatureTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_ownerTb4b4b4.Te6edf3identityTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3signTb4b4b4(Te6edf3signed_dataTb4b4b4)Tb4b4b4)Tb4b4b4;

Te6edf3Bytes Te6edf3proof_data Tff7b72= Te6edf3signature Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytesTb4b4b4;
T8b949e// CBA LINK
T8b949e// CBA TODO: Determine which approach is better, passing liunk to packet or passing _link_destination
Te6edf3Packet Td2a8ffproofTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4)Tb4b4b4;
Te6edf3proofTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72+Tff7b72= Te6edf3proofTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3prove_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s proving packetTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffsignatureTb4b4b4(Te6edf3signTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// TODO: Hardcoded as explicit proof for now
T8b949e// if RNS.Reticulum.should_use_implicit_proof():
T8b949e// proof_data = signature
T8b949e// else:
T8b949e// proof_data = packet.packet_hash + signature
Te6edf3Bytes Te6edf3proof_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3signatureTb4b4b4;

Te6edf3Packet Td2a8ffproofTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4)Tb4b4b4;
Te6edf3proofTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3validate_proofTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s validating proofTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3PENDINGTb4b4b4) Tb4b4b4{
Te6edf3Bytes Td2a8ffpacket_dataTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s: initiator: %dTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s: size: %dTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packet_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3signalling_bytesTb4b4b4;
Tffa657uint16_t Te6edf3confirmed_mtu Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3mode_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffValidating link request proof with mode %dTa5d6ff"Tb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3mode Tff7b72!Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_modeTb4b4b4) Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link mode Ta5d6ff"Tff7b72+Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3modeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff in link request proofTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//p if len(packet.data) == RNS.Identity.SIGLENGTH//8+Link.ECPUBSIZE//2+Link.LINK_MTU_SIZE:
Tff7b72if Tb4b4b4(Te6edf3packet_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tff7b72+Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tb4b4b4{
Te6edf3confirmed_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3confirmed_mtuTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
T8b949e// CBA TODO Determine best way to deal with packet.data() being read-only
T8b949e//p packet.data = packet.data[:RNS.Identity.SIGLENGTH//8+Link.ECPUBSIZE//2]
Te6edf3packet_data Tff7b72= Te6edf3packet_dataTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffDestination confirmed link MTU of %dTa5d6ff"Tb4b4b4, Te6edf3confirmed_mtuTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e//p if _object->_initiator and len(packet.data) == RNS.Identity.SIGLENGTH//8+ECPUBSIZE//2:
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiator Tff7b72&Tff7b72& Te6edf3packet_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tff7b72+Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4) Tb4b4b4{
T8b949e//p peer_pub_bytes = packet.data[RNS.Identity.SIGLENGTH//8:RNS.Identity.SIGLENGTH//8+ECPUBSIZE//2]
Tff7b72const Te6edf3Bytes Td2a8ffpeer_pub_bytesTb4b4b4(Te6edf3packet_dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p peer_sig_pub_bytes = _object->_destination.identity.get_public_key()[ECPUBSIZE//2:ECPUBSIZE]
Tff7b72const Te6edf3Bytes Te6edf3peer_sig_pub_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3identityTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4, Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s performing handshakeTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3load_peerTb4b4b4(Te6edf3peer_pub_bytesTb4b4b4, Te6edf3peer_sig_pub_bytesTb4b4b4)Tb4b4b4;
Te6edf3handshakeTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72+Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3signed_data Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_id Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_pub_bytes Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_sig_pub_bytesTb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffsignatureTb4b4b4(Te6edf3packet_dataTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s validating identityTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3identityTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3validateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3HANDSHAKETb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link state for proof validation: Ta5d6ff" Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_statusTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_timeTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_attached_interface Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identity Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3identityTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3confirmed_mtuTb4b4b4) Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtu Tff7b72= Te6edf3confirmed_mtuTb4b4b4;
Tff7b72else Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtu Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4;
Te6edf3update_mduTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_activated_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_proof Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_activated_atTb4b4b4;
Te6edf3TransportTff7b72:Tff7b72:Te6edf3activate_linkTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s established with %s, RTT is %f sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3roundTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rttTb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p if _object->_rtt != None and _object->_establishment_cost != None and _object->_rtt > 0 and _object->_establishment_cost > 0:
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72!Tff7b72= T79c0ff0.0 Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72> T79c0ff0 Tff7b72and Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_rate Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72/ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rttTb4b4b4;
Tb4b4b4}

T8b949e//p rtt_data = umsgpack.packb(self.rtt)
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Packer Te6edf3packerTb4b4b4;
Te6edf3packerTb4b4b4.Te6edf3serializeTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rttTb4b4b4)Tb4b4b4;
Te6edf3Bytes Td2a8ffrtt_dataTb4b4b4(Te6edf3packerTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packerTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ff***** RTT data size: %dTa5d6ff"Tb4b4b4, Te6edf3rtt_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p rtt_packet = RNS.Packet(self, rtt_data, context=RNS.Packet.LRRTT)
Te6edf3Packet Td2a8ffrtt_packetTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3rtt_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRRTTTb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ff***** RTT packet data: %sTa5d6ff"Tb4b4b4, Te6edf3rtt_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3rtt_packetTb4b4b4.Te6edf3packTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Packet Td2a8fftest_packetTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3DestinationTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4)Tb4b4b4, Te6edf3rtt_packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3test_packetTb4b4b4.Te6edf3unpackTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ff***** RTT test packet destination hash: %sTa5d6ff"Tb4b4b4, Te6edf3test_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ff***** RTT test packet data size: %dTa5d6ff"Tb4b4b4, Te6edf3test_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ff***** RTT test packet data: %sTa5d6ff"Tb4b4b4, Te6edf3test_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3plaintext Tff7b72= Te6edf3decryptTb4b4b4(Te6edf3test_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ff***** RTT test packet plaintext: %sTa5d6ff"Tb4b4b4, Te6edf3plaintextTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3rtt_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_established Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s is establishedTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p thread = threading.Thread(target=_object->_callbacks.link_established, args=(self,))
T8b949e//p thread.daemon = True
T8b949e//p thread.start()
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_establishedTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link proof signature received by %s. Ignoring.Ta5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffFailed initiator/size check for link proof signature received by %s. Ignoring.Ta5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while validating link request proof on %s.Ta5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}


T8b949e/*
Identifies the initiator of the link to the remote peer. This can only happen
once the link has been established, and is carried out over the encrypted link.
The identity is only revealed to the remote peer, and initiator anonymity is
thus preserved. This method can be used for authentication.

:param identity: An RNS.Identity instance to identify as.
*/
Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3identifyTb4b4b4(Tff7b72const Te6edf3IdentityTff7b72& Te6edf3identityTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s requesting identityTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiator Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3Bytes Td2a8ffsigned_dataTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_id Tff7b72+ Te6edf3identityTb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffsignatureTb4b4b4(Te6edf3identityTb4b4b4.Te6edf3signTb4b4b4(Te6edf3signed_dataTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffproof_dataTb4b4b4(Te6edf3identityTb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3signatureTb4b4b4)Tb4b4b4;

Te6edf3Packet Td2a8ffproofTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKIDENTIFYTb4b4b4)Tb4b4b4;
Te6edf3proofTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

T8b949e/*
Sends a request to the remote peer.

:param path: The request path.
:param response_callback: An optional function or method with the signature *response_callback(request_receipt)* to be called when a response is received. See the :ref:`Request Example<example-request>` for more info.
:param failed_callback: An optional function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the :ref:`Request Example<example-request>` for more info.
:param progress_callback: An optional function or method with the signature *progress_callback(request_receipt)* to be called when progress is made receiving the response. Progress can be accessed as a float between 0.0 and 1.0 by the *request_receipt.progress* property.
:param timeout: An optional timeout in seconds for the request. If *None* is supplied it will be calculated based on link RTT.
:returns: A :ref:`RNS.RequestReceipt<api-requestreceipt>` instance if the request was sent, or *False* if it was not.
*/
Tff7b72const Te6edf3RNSTff7b72:Tff7b72:Te6edf3RequestReceipt Te6edf3LinkTff7b72:Tff7b72:Te6edf3requestTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3pathTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3data T8b949e/*= {Bytes::NONE}*/Tb4b4b4, Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3response Te6edf3response_callback T8b949e/*= nullptr*/Tb4b4b4, Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3failed Te6edf3failed_callback T8b949e/*= nullptr*/Tb4b4b4, Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3progress Te6edf3progress_callback T8b949e/*= nullptr*/Tb4b4b4, Tffa657double Te6edf3timeout T8b949e/*= 0.0*/Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s sending requestTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffrequest_path_hashTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4)Tb4b4b4;

T8b949e//p unpacked_request = [OS::time(), request_path_hash, data]
T8b949e//p packed_request = umsgpack.packb(unpacked_request)
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Packer Te6edf3packerTb4b4b4;
Te6edf3packerTb4b4b4.Te6edf3to_arrayTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3request_path_hashTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4;
Te6edf3Bytes Td2a8ffpacked_requestTb4b4b4(Te6edf3packerTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packerTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3timeout Tff7b72=Tff7b72= T79c0ff0.0Tb4b4b4) Tb4b4b4{
Te6edf3timeout Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72* Te6edf3_objectTff7b72-Tff7b72>Te6edf3_traffic_timeout_factor Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3ResourceTff7b72:Tff7b72:Te6edf3RESPONSE_MAX_GRACE_TIME Tff7b72* T79c0ff1.125Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3packed_requestTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3MDUTb4b4b4) Tb4b4b4{
Te6edf3Packet Td2a8ffrequest_packetTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3packed_requestTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3REQUESTTb4b4b4)Tb4b4b4;
Te6edf3PacketReceipt Te6edf3packet_receipt Tff7b72= Te6edf3request_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packet_receiptTb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3packet_receiptTb4b4b4.Te6edf3set_timeoutTb4b4b4(Te6edf3timeoutTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3RequestReceiptTb4b4b4(
Tff7b72*Tff7b72thisTb4b4b4,
Te6edf3packet_receiptTb4b4b4,
Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4,
Te6edf3response_callbackTb4b4b4,
Te6edf3failed_callbackTb4b4b4,
Te6edf3progress_callbackTb4b4b4,
Te6edf3timeoutTb4b4b4,
Te6edf3packed_requestTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72const Te6edf3Bytes Td2a8ffrequest_idTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3packed_requestTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSending request %s as resource.Ta5d6ff"Tb4b4b4, Te6edf3request_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Resource Td2a8ffrequest_resourceTb4b4b4(Te6edf3packed_requestTb4b4b4, Tff7b72*Tff7b72thisTb4b4b4, Te6edf3request_idTb4b4b4, Tffa657falseTb4b4b4, Te6edf3timeoutTb4b4b4)Tb4b4b4;

Tff7b72return Te6edf3RequestReceiptTb4b4b4(
Tff7b72*Tff7b72thisTb4b4b4,
Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4,
Te6edf3request_resourceTb4b4b4,
Te6edf3response_callbackTb4b4b4,
Te6edf3failed_callbackTb4b4b4,
Te6edf3progress_callbackTb4b4b4,
Te6edf3timeoutTb4b4b4,
Te6edf3packed_requestTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}


Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3update_mduTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mdu Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtu Tff7b72- Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3HEADER_MAXSIZE Tff7b72- Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3IFAC_MIN_SIZETb4b4b4;
T8b949e//p self.mdu = math.floor((self.mtu-RNS.Reticulum.IFAC_MIN_SIZE-RNS.Reticulum.HEADER_MINSIZE-RNS.Identity.TOKEN_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mdu Tff7b72= Te6edf3floorTb4b4b4(Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtuTff7b72-Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3IFAC_MIN_SIZETff7b72-Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3HEADER_MINSIZETff7b72-Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TOKEN_OVERHEADTb4b4b4)Tff7b72/Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3AES128_BLOCKSIZETb4b4b4)Tff7b72*Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3AES128_BLOCKSIZE Tff7b72- T79c0ff1Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3rtt_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tffa657double Te6edf3measured_rtt Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_timeTb4b4b4;
Tff7b72const Te6edf3Bytes Td2a8ffplaintextTb4b4b4(Te6edf3decryptTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3plaintextTb4b4b4) Tb4b4b4{
T8b949e//p rtt = umsgpack.unpackb(plaintext)
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Unpacker Te6edf3unpackerTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3plaintextTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3plaintextTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3rtt Tff7b72= T79c0ff0.0Tb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3deserializeTb4b4b4(Te6edf3rttTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3measured_rttTb4b4b4, Te6edf3rttTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_activated_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;

T8b949e//p if _object->_rtt != None and _object->_establishment_cost != None and _object->_rtt > 0 and _object->_establishment_cost > 0:
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72!Tff7b72= T79c0ff0.0 Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72!Tff7b72= T79c0ff0.0 Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rtt Tff7b72> T79c0ff0 Tff7b72and Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_rate Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72/ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rttTb4b4b4;
Tb4b4b4}

Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_ownerTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_link_established Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_ownerTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_link_establishedTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError occurred in external link establishment callback. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while processing RTT packet, tearing down link. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3teardownTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

T8b949e/*
:returns: The data transfer rate at which the link establishment procedure ocurred, in bits per second.
*/
Tffa657float Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_establishment_rateTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
T8b949e//p if _object->_establishment_rate != None:
T8b949e//p return _object->_establishment_rate*8
T8b949e//p else:
T8b949e//p return None
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_rateTff7b72*T79c0ff8Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The MTU of an established link.
*/
Tffa657uint16_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_mtuTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtuTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The packet MDU of an established link.
*/
Tffa657uint16_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_mduTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mduTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The packet expected in-flight data rate of an established link.
*/
Tffa657float Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_expected_rateTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_expected_rateTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The mode of an established link.
*/
Te6edf3link_mode Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_modeTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_modeTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3BytesTff7b72& Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_saltTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3Bytes Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_contextTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The time in seconds since this link was established.
*/
Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_ageTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_activated_atTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_objectTff7b72-Tff7b72>Te6edf3_activated_atTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The time in seconds since last inbound packet on the link. This includes keepalive packets.
*/
Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3no_inbound_forTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
T8b949e//p activated_at = _object->_activated_at if _object->_activated_at != None else 0
Tffa657double Te6edf3activated_at Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_activated_atTb4b4b4;
Tffa657double Te6edf3last_inbound Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_inboundTb4b4b4, Te6edf3activated_atTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_inboundTb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The time in seconds since last outbound packet on the link. This includes keepalive packets.
*/
Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3no_outbound_forTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_outboundTb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The time in seconds since payload data traversed the link. This excludes keepalive packets.
*/
Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3no_data_forTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_dataTb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The time in seconds since activity on the link. This includes keepalive packets.
*/
Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3inactive_forTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3no_inbound_forTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3no_outbound_forTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/*
:returns: The identity of the remote peer, if it is known. Calling this method will not query the remote initiator to reveal its identity. Returns ``None`` if the link initiator has not already independently called the ``identify(identity)`` method.
*/
Tff7b72const Te6edf3IdentityTff7b72& Te6edf3LinkTff7b72:Tff7b72:Te6edf3get_remote_identityTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identityTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3had_outboundTb4b4b4(Tffa657bool Te6edf3is_keepalive T8b949e/*= false*/Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_outbound Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_keepaliveTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_data Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_outboundTb4b4b4;
Tb4b4b4}
Tb4b4b4}

T8b949e/*
Closes the link and purges encryption keys. New keys will
be used if a new link to the same destination is established.
*/
Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3teardownTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3PENDING Tff7b72&Tff7b72& Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
Te6edf3Packet Td2a8ffteardown_packetTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKCLOSETb4b4b4)Tb4b4b4;
Te6edf3teardown_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_teardown_reason Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3INITIATOR_CLOSEDTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_teardown_reason Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3DESTINATION_CLOSEDTb4b4b4;
Tb4b4b4}
Te6edf3link_closedTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3teardown_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Te6edf3Bytes Te6edf3plaintext Tff7b72= Te6edf3decryptTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3plaintext Tff7b72=Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_teardown_reason Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3DESTINATION_CLOSEDTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_teardown_reason Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3INITIATOR_CLOSEDTb4b4b4;
Tb4b4b4}
Te6edf3link_closedTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_closedTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3resource Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3ResourceTff7b72&Tff7b72>Tb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3resource Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3ResourceTff7b72&Tff7b72>Tb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_channelTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_channelTb4b4b4.Te6edf3_shutdownTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pubTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytesTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_shared_keyTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_derived_keyTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3directionTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3has_linkTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3remove_linkTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_closedTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_closedTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing link closed callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e// CBA TODO Implement watchdog
Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3start_watchdogTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e//z thread = threading.Thread(target=_object->___watchdog_job)
T8b949e//z thread.daemon = True
T8b949e//z thread.start()
Tb4b4b4}

T8b949e/*p TODO

void Link::__watchdog_job() {
assert(_object);
while not _object->_status == Type::Link::CLOSED:
while (_object->_watchdog_lock):
rtt_wait = 0.025
if hasattr(self, "rtt") and _object->_rtt:
rtt_wait = _object->_rtt

sleep(max(rtt_wait, 0.025))

if not _object->_status == Type::Link::CLOSED:
# Link was initiated, but no response
# from destination yet
if _object->_status == PENDING:
next_check = _object->_request_time + _object->_establishment_timeout
sleep_time = next_check - OS::time()
if OS::time() >= _object->_request_time + _object->_establishment_timeout:
RNS.log("Link establishment timed out", RNS.LOG_VERBOSE)
_object->_status = Type::Link::CLOSED
_object->_teardown_reason = TIMEOUT
link_closed()
sleep_time = 0.001

elif _object->_status == Type::Link::HANDSHAKE:
next_check = _object->_request_time + _object->_establishment_timeout
sleep_time = next_check - OS::time()
if OS::time() >= _object->_request_time + _object->_establishment_timeout:
_object->_status = Type::Link::CLOSED
_object->_teardown_reason = TIMEOUT
link_closed()
sleep_time = 0.001

if _object->_initiator:
RNS.log("Timeout waiting for link request proof", RNS.LOG_DEBUG)
else:
RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG)

elif _object->_status == Type::Link::ACTIVE:
activated_at = _object->_activated_at if _object->_activated_at != None else 0
last_inbound = max(max(_object->_last_inbound, _object->_last_proof), activated_at)

if OS::time() >= last_inbound + _object->_keepalive:
if _object->_initiator:
send_keepalive()

if OS::time() >= last_inbound + _object->_stale_time:
sleep_time = _object->_rtt * _object->_keepalive_timeout_factor + STALE_GRACE
_object->_status = STALE
else:
sleep_time = _object->_keepalive
else:
sleep_time = (last_inbound + _object->_keepalive) - OS::time()

elif _object->_status == STALE:
sleep_time = 0.001
_object->_status = Type::Link::CLOSED
_object->_teardown_reason = TIMEOUT
link_closed()


if sleep_time == 0:
RNS.log("Warning! Link watchdog sleep time of 0!", RNS.LOG_ERROR)
if sleep_time == None or sleep_time < 0:
RNS.log("Timing error! Tearing down link "+str(self)+" now.", RNS.LOG_ERROR)
teardown()
sleep_time = 0.1

sleep(sleep_time)

*/

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3send_keepaliveTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
T8b949e//p keepalive_packet = RNS.Packet(self, bytes([0xFF]), context=RNS.Packet.KEEPALIVE)
Te6edf3RNSTff7b72:Tff7b72:Te6edf3Packet Te6edf3keepalive_packetTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3BytesTb4b4b4(Ta5d6ff"Tffea00\xFFTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVETb4b4b4)Tb4b4b4;
Te6edf3keepalive_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3handle_requestTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3request_idTb4b4b4, Tff7b72const Te6edf3ResourceRequestTff7b72& Te6edf3resource_requestTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffLink %s handling requestTa5d6ff"Tb4b4b4, Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4) Tb4b4b4{
T8b949e//p requested_at = unpacked_request[0]
T8b949e//p path_hash = unpacked_request[1]
T8b949e//p request_data = unpacked_request[2]

Tff7b72auto Te6edf3handler_iter Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3request_handlersTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3findTb4b4b4(Te6edf3resource_requestTb4b4b4.Te6edf3_path_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3handler_iter Tff7b72!Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3request_handlersTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffLink::handle_request: Found handlerTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3RequestHandler Te6edf3request_handler Tff7b72= Tb4b4b4(Tff7b72*Te6edf3handler_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;

Tffa657bool Te6edf3allowed Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3request_handlerTb4b4b4.Te6edf3_allow Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3ALLOW_NONETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3request_handlerTb4b4b4.Te6edf3_allow Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3ALLOW_LISTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identity Tff7b72&Tff7b72& Te6edf3request_handlerTb4b4b4.Te6edf3_allowed_listTb4b4b4.Te6edf3countTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3request_handlerTb4b4b4.Te6edf3_allow Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3ALLOW_ALLTb4b4b4) Tb4b4b4{
Te6edf3allowed Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3allowedTb4b4b4) Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffHandling request %s for: %sTa5d6ff"Tb4b4b4, Te6edf3request_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3request_handlerTb4b4b4.Te6edf3_pathTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p if len(inspect.signature(response_generator).parameters) == 5:
T8b949e//p response = response_generator(path, request_data, request_id, _object->__remote_identity, requested_at)
T8b949e//p elif len(inspect.signature(response_generator).parameters) == 6:
T8b949e//p response = response_generator(path, request_data, request_id, _object->_link_id, _object->__remote_identity, requested_at)
T8b949e//p else:
T8b949e//p raise TypeError("Invalid signature for response generator callback")
Te6edf3Bytes Td2a8ffresponseTb4b4b4(Te6edf3request_handlerTb4b4b4.Te6edf3_response_generatorTb4b4b4(Te6edf3request_handlerTb4b4b4.Te6edf3_pathTb4b4b4, Te6edf3resource_requestTb4b4b4.Te6edf3_request_dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identityTb4b4b4, Te6edf3resource_requestTb4b4b4.Te6edf3_requested_atTb4b4b4)Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3responseTb4b4b4) Tb4b4b4{
T8b949e//p packed_response = umsgpack.packb([request_id, response])
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Packer Te6edf3packerTb4b4b4;
Te6edf3packerTb4b4b4.Te6edf3to_arrayTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3responseTb4b4b4)Tb4b4b4;
Te6edf3Bytes Td2a8ffpacked_responseTb4b4b4(Te6edf3packerTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packerTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3packed_responseTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3MDUTb4b4b4) Tb4b4b4{
T8b949e//p RNS.Packet(self, packed_response, Type::Packet::DATA, context = Type::Packet::RESPONSE).send()
Te6edf3RNSTff7b72:Tff7b72:Te6edf3Packet Td2a8ffresponse_packetTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3packed_responseTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESPONSETb4b4b4)Tb4b4b4;
Te6edf3response_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// CBA TODO Determine why unused Resource is created here
Te6edf3Resource Te6edf3response_resource Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3ResourceTb4b4b4(Te6edf3packed_responseTb4b4b4, Tff7b72*Tff7b72thisTb4b4b4, Te6edf3request_idTb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3identity_stringTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3get_remote_identityTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3identity_string Tff7b72= Te6edf3get_remote_identityTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3identity_string Tff7b72= Ta5d6ff"Ta5d6ff<Unknown>Ta5d6ff"Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffRequest %s from %s not allowed for: %sTa5d6ff"Tb4b4b4, Te6edf3request_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3identity_stringTb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3request_handlerTb4b4b4.Te6edf3_pathTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3handle_responseTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3request_idTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3response_dataTb4b4b4, Tffa657size_t Te6edf3response_sizeTb4b4b4, Tffa657size_t Te6edf3response_transfer_sizeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Te6edf3RNSTff7b72:Tff7b72:Te6edf3RequestReceipt Te6edf3remove Tff7b72= Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tff7b72for Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3RequestReceipt Te6edf3pending_request Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pending_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pending_requestTb4b4b4.Te6edf3request_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3request_idTb4b4b4) Tb4b4b4{
Te6edf3remove Tff7b72= Te6edf3pending_requestTb4b4b4;
Tff7b72try Tb4b4b4{
Te6edf3pending_requestTb4b4b4.Te6edf3response_sizeTb4b4b4(Te6edf3response_sizeTb4b4b4)Tb4b4b4;
T8b949e//if (pending_request.response_transfer_size == 0) {
T8b949e// pending_request.response_transfer_size = 0;
T8b949e//}
Te6edf3pending_requestTb4b4b4.Te6edf3response_transfer_sizeTb4b4b4(Te6edf3pending_requestTb4b4b4.Te6edf3response_transfer_sizeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3response_transfer_sizeTb4b4b4)Tb4b4b4;
Te6edf3pending_requestTb4b4b4.Te6edf3response_receivedTb4b4b4(Te6edf3response_dataTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling response. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3removeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pending_requestsTb4b4b4.Te6edf3countTb4b4b4(Te6edf3removeTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pending_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3removeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3request_resource_concludedTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3resourceTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3ResourceTff7b72:Tff7b72:Te6edf3COMPLETETb4b4b4) Tb4b4b4{
T8b949e//p packed_request = resource.data().read()
Te6edf3Bytes Te6edf3packed_request Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//p unpacked_request = umsgpack.unpackb(packed_request)
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Unpacker Te6edf3unpackerTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3packed_requestTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packed_requestTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CBA TODO OPTIMIZE MSGPACK
Tffa657double Te6edf3requested_atTb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3path_hashTb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3request_dataTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3from_arrayTb4b4b4(Te6edf3requested_atTb4b4b4, Te6edf3path_hashTb4b4b4, Te6edf3request_dataTb4b4b4)Tb4b4b4;
Te6edf3ResourceRequest Te6edf3resource_requestTb4b4b4;
Te6edf3resource_requestTb4b4b4.Te6edf3_requested_at Tff7b72= Te6edf3requested_atTb4b4b4;
Te6edf3resource_requestTb4b4b4.Te6edf3_path_hash Tff7b72= Te6edf3path_hashTb4b4b4;
Te6edf3resource_requestTb4b4b4.Te6edf3_request_data Tff7b72= Te6edf3request_dataTb4b4b4;
T8b949e//p request_id = RNS.Identity.truncated_hash(packed_request)
Te6edf3Bytes Td2a8ffrequest_idTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3resourceTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//p request_data = unpacked_request

T8b949e//p handle_request(request_id, request_data)
Te6edf3handle_requestTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3resource_requestTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffIncoming request resource failed with status: %dTa5d6ff"Tb4b4b4, Te6edf3resourceTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3response_resource_concludedTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3resourceTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3ResourceTff7b72:Tff7b72:Te6edf3COMPLETETb4b4b4) Tb4b4b4{
T8b949e//p packed_response = resource.data.read()
Te6edf3Bytes Te6edf3packed_response Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//p unpacked_response = umsgpack.unpackb(packed_response)
T8b949e//p request_id = unpacked_response[0]
T8b949e//p response_data = unpacked_response[1]
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Unpacker Te6edf3unpackerTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3packed_responseTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packed_responseTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3request_idTb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3response_dataTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3from_arrayTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3response_dataTb4b4b4)Tb4b4b4;

Te6edf3handle_responseTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3response_dataTb4b4b4, Te6edf3resourceTb4b4b4.Te6edf3total_sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3resourceTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffIncoming response resource failed with status: %dTa5d6ff"Tb4b4b4, Te6edf3resourceTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3RequestReceipt Te6edf3pending_request Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pending_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pending_requestTb4b4b4.Te6edf3request_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3request_idTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3pending_requestTb4b4b4.Te6edf3request_timed_outTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}


T8b949e/*z
"""
Get the ``Channel`` for this link.

:return: ``Channel`` object
"""
void Link::get_channel() {
assert(_object);
if _object->_channel is None:
_object->_channel = Channel(LinkChannelOutlet(self))
return _object->_channel
*/

T8b949e/*
void Link::receive(const Packet& packet) {
}
*/
Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3receiveTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_watchdog_lock Tff7b72= Tffa657trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSED Tff7b72&Tff7b72& Tff7b72!Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiator Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Ta5d6ff"Tffea00\xFFTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_attached_interfaceTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffLink-associated packet received on unexpected interface! Someone might be trying to manipulate your communication!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_inbound Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVETb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_data Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_inboundTb4b4b4;
Tb4b4b4}
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rx Tff7b72+Tff7b72= T79c0ff1Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rxbytes Tff7b72+Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3STALETb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3should_query Tff7b72= Tffa657falseTb4b4b4;
Tff7b72switch Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72CONTEXT_NONETb4b4b4:
Tb4b4b4{
Tff7b72const Te6edf3Bytes Te6edf3plaintext Tff7b72= Te6edf3decryptTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3plaintextTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_packetTb4b4b4) Tb4b4b4{
T8b949e//z thread = threading.Thread(target=_object->_callbacks.packet, args=(plaintext, packet))
T8b949e//z thread.daemon = True
T8b949e//z thread.start()
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_packetTb4b4b4(Te6edf3plaintextTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing packet callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3proof_strategyTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_ALLTb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3PacketTff7b72&Tff7b72>Tb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3should_query Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3proof_strategyTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_APPTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_proof_requestedTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_proof_requestedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3PacketTff7b72&Tff7b72>Tb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3should_query Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing proof request callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72LINKIDENTIFYTb4b4b4:
Tb4b4b4{
Tff7b72const Te6edf3Bytes Te6edf3plaintext Tff7b72= Te6edf3decryptTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3plaintextTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4) Tff7b72&Tff7b72& Te6edf3plaintextTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3Bytes Te6edf3public_key Tff7b72= Te6edf3plaintextTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3Bytes Te6edf3signed_data Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_id Tff7b72+ Te6edf3public_keyTb4b4b4;
Tff7b72const Te6edf3Bytes Te6edf3signature Tff7b72= Te6edf3plaintextTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Te6edf3Identity Td2a8ffidentityTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3identityTb4b4b4.Te6edf3load_public_keyTb4b4b4(Te6edf3public_keyTb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3identityTb4b4b4.Te6edf3validateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identity Tff7b72= Te6edf3identityTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_remote_identifiedTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_remote_identifiedTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3__remote_identityTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing remote identified callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72REQUESTTb4b4b4:
Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3Bytes Te6edf3request_id Tff7b72= Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3Bytes Te6edf3packed_request Tff7b72= Te6edf3decryptTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packed_requestTb4b4b4) Tb4b4b4{
T8b949e//p unpacked_request = umsgpack.unpackb(packed_request)
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Unpacker Te6edf3unpackerTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3packed_requestTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packed_requestTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CBA TODO OPTIMIZE MSGPACK
Tffa657double Te6edf3requested_atTb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3path_hashTb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3request_dataTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3from_arrayTb4b4b4(Te6edf3requested_atTb4b4b4, Te6edf3path_hashTb4b4b4, Te6edf3request_dataTb4b4b4)Tb4b4b4;
Te6edf3ResourceRequest Te6edf3resource_requestTb4b4b4;
Te6edf3resource_requestTb4b4b4.Te6edf3_requested_at Tff7b72= Te6edf3requested_atTb4b4b4;
Te6edf3resource_requestTb4b4b4.Te6edf3_path_hash Tff7b72= Te6edf3path_hashTb4b4b4;
Te6edf3resource_requestTb4b4b4.Te6edf3_request_data Tff7b72= Te6edf3request_dataTb4b4b4;
Te6edf3handle_requestTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3resource_requestTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling request. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72RESPONSETb4b4b4:
Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3Bytes Te6edf3packed_response Tff7b72= Te6edf3decryptTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packed_responseTb4b4b4) Tb4b4b4{
T8b949e//p unpacked_response = umsgpack.unpackb(packed_response)
T8b949e//p request_id = unpacked_response[0]
T8b949e//p response_data = unpacked_response[1]
T8b949e//p transfer_size = len(umsgpack.packb(response_data))-2
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Unpacker Te6edf3unpackerTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3packed_responseTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packed_responseTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3request_idTb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3bin_tTff7b72<Tffa657uint8_tTff7b72> Te6edf3response_dataTb4b4b4;
Te6edf3unpackerTb4b4b4.Te6edf3from_arrayTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3response_dataTb4b4b4)Tb4b4b4;
Te6edf3MsgPackTff7b72:Tff7b72:Te6edf3Packer Te6edf3packerTb4b4b4;
Te6edf3packerTb4b4b4.Te6edf3serializeTb4b4b4(Te6edf3response_dataTb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3transfer_size Tff7b72= Te6edf3packerTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff2Tb4b4b4;
Te6edf3handle_responseTb4b4b4(Te6edf3BytesTb4b4b4(Te6edf3request_idTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3request_idTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3BytesTb4b4b4(Te6edf3response_dataTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3response_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3transfer_sizeTb4b4b4, Te6edf3transfer_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling response. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72LRRTTTb4b4b4:
Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4) Tb4b4b4{
Te6edf3rtt_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72LINKCLOSETb4b4b4:
Tb4b4b4{
Te6edf3teardown_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
T8b949e/*z
case Type::Packet::RESOURCE_ADV:
{
//p packet.plaintext = decrypt(packet.data)
const Bytes plaintext = decrypt(packet.data());
if (plaintext) {
const_cast<Packet&>(packet).plaintext(plaintext);
if (ResourceAdvertisement::is_request(packet)) {
Resource::accept(packet, callback=_object->_request_resource_concluded);
}
else if (ResourceAdvertisement::is_response(packet)) {
Bytes request_id = ResourceAdvertisement::read_request_id(packet)
for (auto& pending_request : _object->_pending_requests) {
if (pending_request.request_id == request_id) {
const Bytes response_resource = Resource::accept(packet, callback=_object->_response_resource_concluded, progress_callback=pending_request.response_resource_progress, request_id = request_id);
if (response_resource) {
//p if pending_request.response_size == None:
if (pending_request.response_size == 0) {
pending_request.response_size = ResourceAdvertisement::read_size(packet);
}
//p if pending_request.response_transfer_size == None:
if (pending_request.response_transfer_size == 0) {
pending_request.response_transfer_size = 0;
}
pending_request.response_transfer_size += ResourceAdvertisement::read_transfer_size(packet);
//p if pending_request.started_at == None:
if (pending_request.started_at == 0.0) {
pending_request.started_at = OS::time();
}
pending_request.response_resource_progress(response_resource);
}
}
}
}
else if (_object->_resource_strategy == ACCEPT_NONE) {
//p pass
}
else if (_object->_resource_strategy == ACCEPT_APP) {
if (_object->_callbacks.resource) {
try {
resource_advertisement = RNS.ResourceAdvertisement.unpack(packet.plaintext());
resource_advertisement.link = *this;
if (_object->_callbacks.resource(resource_advertisement)) {
Resource::accept(packet, _object->_callbacks.resource_concluded);
}
}
catch (std::exception& e) {
ERRORF("Error while executing resource accept callback from %s. The contained exception was: %s", toString().c_str(), e.what());
}
elif _object->_resource_strategy == ACCEPT_ALL:
RNS.Resource.accept(packet, _object->_callbacks.resource_concluded)
break;
}
case Type::Packet::RESOURCE_REQ:
{
const Bytes plaintext = decrypt(packet.data());
if (plaintext) {
if ord(plaintext[:1]) == RNS.Resource.HASHMAP_IS_EXHAUSTED:
resource_hash = plaintext[1+RNS.Resource.MAPHASH_LEN:Type::Identity::HASHLENGTH//8+1+RNS.Resource.MAPHASH_LEN]
else:
resource_hash = plaintext[1:Type::Identity::HASHLENGTH//8+1]

for resource in _object->_outgoing_resources:
if resource.hash == resource_hash:
// We need to check that this request has not been
// received before in order to avoid sequencing errors.
if not packet.packet_hash in resource.req_hashlist:
resource.req_hashlist.append(packet.packet_hash)
resource.request(plaintext)
break;
}
case Type::Packet::RESOURCE_HMU:
{
const Bytes plaintext = decrypt(packet.data());
if (plaintext) {
resource_hash = plaintext[:Type::Identity::HASHLENGTH//8]
for resource in _object->_incoming_resources:
if resource_hash == resource.hash:
resource.hashmap_update_packet(plaintext)
break;
}
case Type::Packet::RESOURCE_ICL:
{
const Bytes plaintext = decrypt(packet.data());
if (plaintext) {
resource_hash = plaintext[:Type::Identity::HASHLENGTH//8]
for resource in _object->_incoming_resources:
if resource_hash == resource.hash:
resource.cancel()
break;
}
*/
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72KEEPALIVETb4b4b4:
Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiator Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Ta5d6ff"Tffea00\xFFTa5d6ff"Tb4b4b4) Tb4b4b4{
T8b949e//p keepalive_packet = RNS.Packet(self, bytes([0xFE]), context=RNS.Packet.KEEPALIVE)
Te6edf3Packet Te6edf3keepalive_packetTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4, Te6edf3BytesTb4b4b4(Ta5d6ff"Tffea00\xFETa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVETb4b4b4)Tb4b4b4;
Te6edf3keepalive_packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3had_outboundTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
T8b949e// TODO: find the most efficient way to allow multiple
T8b949e// transfers at the same time, sending resource hash on
T8b949e// each packet is a huge overhead. Probably some kind
T8b949e// of hash -> sequence map
Tff7b72case Tff7b72TypeTff7b72:Tff7b72:Tff7b72PacketTff7b72:Tff7b72:Tff7b72RESOURCETb4b4b4:
Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3resource Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4) Tb4b4b4{
T8b949e//z resource.receive_part(packet);
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
T8b949e/*z
case Type::Packet::CHANNEL:
{
//z if (!_object->_channel) {
if (true) {
DEBUG(f"Channel data received without open channel")
}
else {
//z packet.prove();
//z plaintext = decrypt(packet.data());
//z if (plaintext) {
//z _object->_channel._receive(plaintext);
//z }
}
break;
}
*/
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_PRFTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3resource_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3resource Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3resource_hash Tff7b72=Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//z resource.validate_proof(packet.data());
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_watchdog_lock Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3Bytes Te6edf3LinkTff7b72:Tff7b72:Te6edf3encryptTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3plaintextTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffLink::encrypt: encrypting data...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_tokenTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_tokenTb4b4b4.Te6edf3resetTb4b4b4(Tff7b72new Te6edf3TokenTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_derived_keyTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffCould not instantiate Token while performing encryption on link %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72throw Te6edf3eTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_tokenTff7b72-Tff7b72>Te6edf3encryptTb4b4b4(Te6edf3plaintextTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffEncryption on link %s failed. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72throw Te6edf3eTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72const Te6edf3Bytes Te6edf3LinkTff7b72:Tff7b72:Te6edf3decryptTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3ciphertextTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffLink::decrypt: decrypting data...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_tokenTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_tokenTb4b4b4.Te6edf3resetTb4b4b4(Tff7b72new Te6edf3TokenTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_derived_keyTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_tokenTff7b72-Tff7b72>Te6edf3decryptTb4b4b4(Te6edf3ciphertextTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffDecryption failed on link %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72const Te6edf3Bytes Te6edf3LinkTff7b72:Tff7b72:Te6edf3signTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3messageTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTff7b72-Tff7b72>Te6edf3signTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657bool Te6edf3LinkTff7b72:Tff7b72:Te6edf3validateTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3signatureTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3messageTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_peer_sig_pubTff7b72-Tff7b72>Te6edf3verifyTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_link_established_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3established Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_established Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_link_closed_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3closed Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_closed Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_packet_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3packet Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_packet Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_remote_identified_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3remote_identified Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_remote_identified Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_resource_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3resource Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_resource Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_resource_started_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3resource_started Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_resource_started Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_resource_concluded_callbackTb4b4b4(Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3resource_concluded Te6edf3callbackTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_resource_concluded Tff7b72= Te6edf3callbackTb4b4b4;
Tb4b4b4}


Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3resource_concludedTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3resourceTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3resourceTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

T8b949e/*
Sets the resource strategy for the link.

:param resource_strategy: One of ``RNS.ACCEPT_NONE``, ``RNS.ACCEPT_ALL`` or ``RNS.ACCEPT_APP``. If ``RNS.ACCEPT_APP`` is set, the `resource_callback` will be called to determine whether the resource should be accepted or not.
:raises: *TypeError* if the resource strategy is unsupported.
*/
Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3set_resource_strategyTb4b4b4(Te6edf3resource_strategy Te6edf3strategyTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Tb4b4b4(Te6edf3strategy Tff7b72& Te6edf3resource_strategiesTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffUnsupported resource strategyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_resource_strategy Tff7b72= Te6edf3strategyTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3register_outgoing_resourceTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3register_incoming_resourceTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657bool Te6edf3LinkTff7b72:Tff7b72:Te6edf3has_incoming_resourceTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3incoming_resource Tff7b72: Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3incoming_resourceTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3cancel_outgoing_resourceTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3resourceTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to cancel a non-existing outgoing resourceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3cancel_incoming_resourceTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_incoming_resourcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to cancel a non-existing incoming resourceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657bool Te6edf3LinkTff7b72:Tff7b72:Te6edf3ready_for_new_resourceTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_outgoing_resourcesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3LinkTff7b72:Tff7b72:Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ff"Tb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff"Ta5d6ff{Link:Ta5d6ff" Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff}Ta5d6ff"Tb4b4b4;
Tb4b4b4}

T8b949e// getters

Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3rttTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_rttTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3DestinationTff7b72& Te6edf3LinkTff7b72:Tff7b72:Te6edf3destinationTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destinationTb4b4b4;
Tb4b4b4}

T8b949e// CBA LINK
T8b949e/*
const Destination& Link::link_destination() const {
assert(_object);
return _object->_link_destination;
}
*/

Tff7b72const Te6edf3BytesTff7b72& Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link_idTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3BytesTff7b72& Te6edf3LinkTff7b72:Tff7b72:Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hashTb4b4b4;
Tb4b4b4}

Tffa657uint16_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtuTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtuTb4b4b4;
Tb4b4b4}

Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3status Te6edf3LinkTff7b72:Tff7b72:Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_statusTb4b4b4;
Tb4b4b4}

Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3establishment_timeoutTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_timeoutTb4b4b4;
Tb4b4b4}

Tffa657uint16_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3establishment_costTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_costTb4b4b4;
Tb4b4b4}

Tffa657uint8_t Te6edf3LinkTff7b72:Tff7b72:Te6edf3traffic_timeout_factorTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_traffic_timeout_factorTb4b4b4;
Tb4b4b4}

Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3request_timeTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_timeTb4b4b4;
Tb4b4b4}

Tffa657double Te6edf3LinkTff7b72:Tff7b72:Te6edf3last_inboundTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_inboundTb4b4b4;
Tb4b4b4}

Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3RNSTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72>Tff7b72& Te6edf3LinkTff7b72:Tff7b72:Te6edf3pending_requestsTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pending_requestsTb4b4b4;
Tb4b4b4}

Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3teardown_reason Te6edf3LinkTff7b72:Tff7b72:Te6edf3teardown_reasonTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_teardown_reasonTb4b4b4;
Tb4b4b4}

Tffa657bool Te6edf3LinkTff7b72:Tff7b72:Te6edf3initiatorTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_initiatorTb4b4b4;
Tb4b4b4}

T8b949e// setters

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3destinationTb4b4b4(Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_destination Tff7b72= Te6edf3destinationTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3attached_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_attached_interface Tff7b72= Te6edf3interfaceTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3establishment_timeoutTb4b4b4(Tffa657double Te6edf3timeoutTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_timeout Tff7b72= Te6edf3timeoutTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3establishment_costTb4b4b4(Tffa657uint16_t Te6edf3costTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_establishment_cost Tff7b72= Te6edf3costTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3request_timeTb4b4b4(Tffa657double Te6edf3timeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_time Tff7b72= Te6edf3timeTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3last_inboundTb4b4b4(Tffa657double Te6edf3timeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_inbound Tff7b72= Te6edf3timeTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3last_outboundTb4b4b4(Tffa657double Te6edf3timeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_last_outbound Tff7b72= Te6edf3timeTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3increment_txTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_txTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3increment_txbytesTb4b4b4(Tffa657uint16_t Te6edf3bytesTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_txbytes Tff7b72+Tff7b72= Te6edf3bytesTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3statusTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3status Te6edf3statusTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3statusTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtuTb4b4b4(Tffa657uint16_t Te6edf3mtuTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mtu Tff7b72= Te6edf3mtuTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3LinkTff7b72:Tff7b72:Te6edf3modeTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3modeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_mode Tff7b72= Te6edf3modeTb4b4b4;
Tb4b4b4}


T8b949e//RequestReceipt::RequestReceipt(const Link& link, const PacketReceipt& packet_receipt /*= {Type::NONE}*/, const Resource& resource /*= {Type::NONE}*/, RequestReceipt::Callbacks::response response_callback /*= nullptr*/, RequestReceipt::Callbacks::failed failed_callback /*= nullptr*/, RequestReceipt::Callbacks::progress progress_callback /*= nullptr*/, double timeout /*= 0.0*/, int request_size /*= 0*/) :
Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3RequestReceiptTb4b4b4(Tff7b72const Te6edf3LinkTff7b72& Te6edf3linkTb4b4b4, Tff7b72const Te6edf3PacketReceiptTff7b72& Te6edf3packet_receiptTb4b4b4, Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4, Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3response Te6edf3response_callback T8b949e/*= nullptr*/Tb4b4b4, Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3failed Te6edf3failed_callback T8b949e/*= nullptr*/Tb4b4b4, Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3CallbacksTff7b72:Tff7b72:Te6edf3progress Te6edf3progress_callback T8b949e/*= nullptr*/Tb4b4b4, Tffa657double Te6edf3timeout T8b949e/*= 0.0*/Tb4b4b4, Tffa657int Te6edf3request_size T8b949e/*= 0*/Tb4b4b4) Tff7b72:
Te6edf3_objectTb4b4b4(Tff7b72new Te6edf3RequestReceiptDataTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receipt Tff7b72= Te6edf3packet_receiptTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_resource Tff7b72= Te6edf3resourceTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hash Tff7b72= Te6edf3packet_receiptTb4b4b4.Te6edf3truncated_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//z _object->_packet_receipt.set_timeout_callback(request_timed_out);
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_started_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_resourceTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hash Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3request_idTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// CBA TODO Need to find cross-platform way of passing class method as callback
T8b949e//z const_cast<Resource&>(resource).set_concluded_callback(request_resource_concluded);
T8b949e//z const_cast<Resource&>(resource).set_concluded_callback(std::bind(&RequestReceipt::request_resource_concluded, this, std::placeholders::_1));
Tb4b4b4}
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_link Tff7b72= Te6edf3linkTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_id Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hashTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_size Tff7b72= Te6edf3request_sizeTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sent_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3timeout Tff7b72!Tff7b72= T79c0ff0.0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_timeout Tff7b72= Te6edf3timeoutTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72throw Tff7b72new Te6edf3stdTff7b72:Tff7b72:Te6edf3invalid_argumentTb4b4b4(Ta5d6ff"Ta5d6ffNo timeout specified for request receiptTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_response Tff7b72= Te6edf3response_callbackTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_failed Tff7b72= Te6edf3failed_callbackTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_progress Tff7b72= Te6edf3progress_callbackTb4b4b4;

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_linkTb4b4b4.Te6edf3pending_requestsTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3insertTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3request_resource_concludedTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3resourceTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3ResourceTff7b72:Tff7b72:Te6edf3COMPLETETb4b4b4) Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffRequest %s successfully sent as resource.Ta5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_started_at Tff7b72=Tff7b72= T79c0ff0.0Tb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_started_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3DELIVEREDTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_resource_response_timeout Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_timeoutTb4b4b4;
T8b949e//p response_timeout_thread = threading.Thread(target=_object->___response_timeout_job)
T8b949e//p response_timeout_thread.daemon = True
T8b949e//p response_timeout_thread.start()
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSending request %s as resource failed with status: %dTa5d6ff"Tb4b4b4, Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3resourceTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3FAILEDTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_concluded_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_linkTb4b4b4.Te6edf3pending_requestsTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3eraseTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_failed Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_failedTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing request failed callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}


Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3__response_timeout_jobTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3DELIVEREDTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72> Te6edf3_objectTff7b72-Tff7b72>Te6edf3___resource_response_timeoutTb4b4b4) Tb4b4b4{
Te6edf3request_timed_outTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(T79c0ff0.1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}


Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3request_timed_outTb4b4b4(Tff7b72const Te6edf3PacketReceiptTff7b72& Te6edf3packet_receiptTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3FAILEDTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_concluded_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_linkTb4b4b4.Te6edf3pending_requestsTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3eraseTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_failed Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_failedTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing request timed out callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}


Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3response_resource_progressTb4b4b4(Tff7b72const Te6edf3ResourceTff7b72& Te6edf3resourceTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3resourceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3FAILEDTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3RECEIVINGTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3DELIVEREDTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3statusTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3DELIVEREDTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3provedTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3concluded_atTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_delivery Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_deliveryTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Te6edf3_objectTff7b72-Tff7b72>Te6edf3_progress Tff7b72= Te6edf3resourceTb4b4b4.Te6edf3get_progressTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_progress Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_progressTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing response progress callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3ResourceTff7b72&Tff7b72>Tb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3response_receivedTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3responseTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3FAILEDTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_progress Tff7b72= T79c0ff1.0Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_response Tff7b72= Te6edf3responseTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3READYTb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_response_concluded_at Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3statusTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3DELIVEREDTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3provedTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3concluded_atTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_delivery Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_deliveryTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_packet_receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_progress Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_progressTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing response progress callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_response Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_callbacksTb4b4b4.Te6edf3_responseTb4b4b4(Tff7b72*Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while executing response received callback from %s. The contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e// :returns: The request ID as *bytes*.
Tff7b72const Te6edf3BytesTff7b72& Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3get_request_idTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_idTb4b4b4;
Tb4b4b4}

T8b949e// :returns: The current status of the request, one of ``RNS.RequestReceipt.FAILED``, ``RNS.RequestReceipt.SENT``, ``RNS.RequestReceipt.DELIVERED``, ``RNS.RequestReceipt.READY``.
Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3status Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3get_statusTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_statusTb4b4b4;
Tb4b4b4}

T8b949e// :returns: The progress of a response being received as a *float* between 0.0 and 1.0.
Tffa657float Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3get_progressTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_progressTb4b4b4;
Tb4b4b4}

T8b949e// :returns: The response as *bytes* if it is ready, otherwise *None*.
Tff7b72const Te6edf3Bytes Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3get_responseTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3READYTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_responseTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4;
Tb4b4b4}
Tb4b4b4}

T8b949e// :returns: The response time of the request in seconds.
Tffa657double Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3get_response_timeTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_status Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3READYTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_response_concluded_at Tff7b72- Te6edf3_objectTff7b72-Tff7b72>Te6edf3_started_atTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"Ta5d6ff"Tb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff"Ta5d6ff{RequestReceipt:Ta5d6ff" Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff}Ta5d6ff"Tb4b4b4;
Tb4b4b4}

T8b949e// getters

Tff7b72const Te6edf3BytesTff7b72& Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hashTb4b4b4;
Tb4b4b4}

Tff7b72const Te6edf3BytesTff7b72& Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3request_idTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_request_idTb4b4b4;
Tb4b4b4}

Tffa657size_t Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3response_transfer_sizeTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_response_transfer_sizeTb4b4b4;
Tb4b4b4}

T8b949e// setters

Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3response_sizeTb4b4b4(Tffa657size_t Te6edf3sizeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_response_size Tff7b72= Te6edf3sizeTb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3RequestReceiptTff7b72:Tff7b72:Te6edf3response_transfer_sizeTb4b4b4(Tffa657size_t Te6edf3sizeTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_response_transfer_size Tff7b72= Te6edf3sizeTb4b4b4;
Tb4b4b4}

Served by rngit 1.4.2 - Generated in 0.2s